import pytickee.errors as errors
import requests
import simplejson as json
import urllib
import logging

def bind_api(**config):
    
    class APIMethod(object):
        
        path = config['path']
        allowed_params = config.get('allowed_params', [])
        method = config.get('method', 'GET')
        require_auth = config.get('require_auth', False)
        
        def __init__(self, api, args, kwargs):
            self.api = api
            # If authentication is required but not provided, throw an error.
            if self.require_auth and not hasattr(self.api, "access_token"):
                raise errors.TickeeError("Authentication required")
            self.parameters = self.prepare_parameters(args, kwargs)
        
        def prepare_parameters(self, args, kwargs):
            for kwarg in kwargs:
                if kwarg not in self.allowed_params:
                    raise errors.TickeeError("Incorrect argument: %s" % kwarg)
            return kwargs.items()
        
        def execute(self):
            # build headers
            headers = {}
            if self.require_auth:
                headers = {'Authorization': 'Bearer %s' % self.api.access_token}
                
            # build request url
            url = self.api.scheme + self.api.host + self.api.api_root + self.path
            # perform the call
            if self.method == 'GET':
                url = "%s?%s" % (url, urllib.urlencode(self.parameters))
                logging.debug("Calling GET: %s" % url)
                response = requests.get(url, headers=headers)
            elif self.method == 'POST':
                logging.debug("Calling POST: %s" % url)
                data = urllib.urlencode(self.parameters)
                response = requests.post(url, data, headers=headers)
            
            logging.debug('HTTP Response code: %s' % response.status_code)
            if response.status_code == 200:
                # parse the response
                result = json.loads(response.content)
            else:
                raise errors.TickeeError("HTTP Status received: %s" % response.status_code)
            
            return result
        
    def _call(api, *args, **kwargs):
        method = APIMethod(api, args, kwargs)
        return method.execute()
        
    return _call